﻿using System;
using System.Collections.Generic;
using System.Linq;
using NOSDC.Pocos;
using System.Linq.Expressions;
using NOSDC.Repositories.Articles;
using NOSDC.Services.Extensions;

namespace NOSDC.Services
{
    public class ArticleService : IArticleService
    {
        private readonly IArticleRepository _repository;

        #region ctors
        public ArticleService(IArticleRepository repository)
        {
            if (repository == null)
                throw new ArgumentException("You must provide a repository");

            _repository = repository;
        }

        public ArticleService() : this(new ArticleRepository()) { }

        #endregion

        public int CreateArticle(Article article)
        {
            return _repository.CreateArticle(article);
        }

        public int UpdateArticle(Article article)
        {
            return _repository.UpdateArticle(article);
        }

        public bool DeleteArticle(int id)
        {
            var article = _repository.GetArticleByID(id);
            bool action = false;

            if (article != null)
            {
                action = _repository.DeleteArticle(article);
            }

            return action;
        }

        public Article GetArticleByID(int id)
        {
            return GetArticleByID(id, false);
        }

        public Article GetArticleByID(int id, bool getComments)
        {
            return _repository.GetArticleByID(id, getComments);
        }

        public IEnumerable<Article> GetArticles(Expression<Func<Article, bool>> expression)
        {
            if (expression == null)
                throw new ArgumentException("You must provide a valid search expression");

            return _repository.GetArticles(expression);
        }

        public IEnumerable<Article> GetAllArticles()
        {
            var articles = _repository.GetAllArticles();
            FormatArticles(articles);
            
            return articles;
        }

        /// <summary>
        /// Performs formatting rules to the result set.
        /// </summary>
        /// <param name="articles">desired articles to format</param>
        private static void FormatArticles(IEnumerable<Article> articles)
        {
            foreach (var a in articles)
            {
                a.Story = a.Story.Truncate(600);
            }
        }

        public IEnumerable<Article> GetFrontpageArticles()
        {
            var articles = _repository.GetFrontpageArticles();
            var frontpageArticles = articles as List<Article> ?? articles.ToList();
            FormatArticles(frontpageArticles);

            return frontpageArticles;
        }
    }
}
